/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mygameframework.util;

import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Vector;

/**
 *
 * @author bill
 */
public class Matrix2D {

     class Matrix{
        double  _11,_12,_13,
                _21,_22,_23,
                _31,_32,_33;
    }
     Matrix mat;
//    private double[][] selfMatrix=new double[3][3];
    public Matrix2D(){
//        System.out.println("mart "+selfMatrix[1][1]);
        mat=new Matrix();
        identity();
    }
    
    //把矩阵初始化为恒等矩阵
    public final void identity(){
        mat._11=1;mat._22=1;mat._33=1;
    }
    /**
     * 
     * @param mat 右矩阵
     */
    public void matrixMultiply(Matrix  rightMat){
        Matrix tmp=new Matrix();
        //first row  
        tmp._11 = (mat._11 * rightMat._11) + (mat._12 * rightMat._21) + (mat._13 * rightMat._31);
        tmp._12 = (mat._11 * rightMat._12) + (mat._12 * rightMat._22) + (mat._13 * rightMat._32);
        tmp._13 = (mat._11 * rightMat._13) + (mat._12 * rightMat._23) + (mat._13 * rightMat._33);

        //second
        tmp._21 = (mat._21 * rightMat._11) + (mat._22 * rightMat._21) + (mat._23 * rightMat._31);
        tmp._22 = (mat._21 * rightMat._12) + (mat._22 * rightMat._22) + (mat._23 * rightMat._32);
        tmp._23 = (mat._21 * rightMat._13) + (mat._22 * rightMat._23) + (mat._23 * rightMat._33);
        //third 
        tmp._31 = (mat._31 * rightMat._11) + (mat._32 * rightMat._21) + (mat._33 * rightMat._31);
        tmp._32 = (mat._31 * rightMat._12) + (mat._32 * rightMat._22) + (mat._33 * rightMat._32);
        tmp._33 = (mat._31 * rightMat._13) + (mat._32 * rightMat._23) + (mat._33 * rightMat._33);
        
        this.mat=tmp;
    }
//    public void matrixMultiply(double[][]  rightMat){
//        double[][] result=new double[3][3];
//        for(int i=0;i<3;i++){
//            for(int j=0;j<3;j++){
//                for(int k=0;k<3;k++){
//                    result[i][j]+=selfMatrix[i][k] * rightMat[k][j];
//                }
//            }
//        }
//        selfMatrix=result;
//    }
    //heading  side 下右矩阵为 笛卡尔坐标系所适用,而游戏坐标系中正Y轴向下,与笛卡尔坐标系相反,
//所以在正转角度时,转的非逆时针,而是转的是顺时针,
//(例如,heading与世界坐标X轴夹角为thetaX,那么该函数的转角实际是-thetaX,
//即让heading与世界坐标X轴重合,再配合位移从而实现把局部坐标转世界坐标)
    public void rotate(Vector2D fwd,Vector2D side){
//        Math.atan2(a, a);
//        double[][] rightMat = {  {fwd.x  ,fwd.y,  0,},
//                            {side.x ,side.y, 0},
//                            {0,     0,      1}};
        Matrix rMat=new Matrix();
        rMat._11=fwd.x ;rMat._12=fwd.y ;rMat._13=0 ;
        rMat._21=side.x ;rMat._22=side.y ;rMat._23=0 ;
        rMat._31=0 ;rMat._32=0;rMat._33=1 ;
        matrixMultiply(rMat);
        
    }
    public void scale(double xScale,double yScale){
        
        Matrix mat=new Matrix();
        mat._11 = xScale; mat._12 = 0; mat._13 = 0;
        mat._21 = 0; mat._22 = yScale; mat._23 = 0;
        mat._31 = 0; mat._32 = 0; mat._33 = 1;
        matrixMultiply(mat);
    }
    public void rotate(float theta) {
        double cos=Math.cos(theta);
        double sin=Math.sin(theta);
//        double[][] rightMat = {  {cos  ,sin,  0,},
//                                 {-sin ,cos, 0},
//                                 {0   ,   0,     1}};
        
        Matrix rMat=new Matrix();
        rMat._11=cos ;rMat._12=sin ;rMat._13=0 ;
        rMat._21=-sin ;rMat._22=cos ;rMat._23=0 ;
        rMat._31=0 ;rMat._32=0;rMat._33=1 ;
        matrixMultiply(rMat);
        
    }
    public List<Vector2D> transformVector2Ds(List<Vector2D> vs){
        for(Vector2D v:vs){
            transformVector2D(v);
        }
        return vs;
    }
    public Vector2D transformVector2D(Vector2D v){
        double tempX=(v.x*mat._11)+(v.y*mat._21)+mat._31;
        double tempY=(v.x*mat._12)+(v.y*mat._22)+mat._32;
        v.x=tempX; v.y=tempY;
        return v;
    }

    private static void printMatrix(Matrix mat) {
        double[][] printArr=new double[3][3];
        printArr[0][0]=mat._11;
        printArr[0][1]=mat._12;
        printArr[0][2]=mat._13;
        
        printArr[1][0]=mat._21;
        printArr[1][1]=mat._22;
        printArr[1][2]=mat._23;
        
        printArr[2][0]=mat._31;
        printArr[2][1]=mat._32;
        printArr[2][2]=mat._33;
        printArray(printArr);
    }
    public static void printArray(double[][] r2) {
        System.out.println("{");
        for (double[] r1 : r2) {
            System.out.print("{");
            for (double i : r1) {
                System.out.print((int)i + " ");
            }
            System.out.println("}");
        }
        System.out.println("}");
    }
    public static void main(String[] args) {
                double[][] arr = {  {1, 2, 0,},
                            {3, 4, 0},
                            {5, 6, 7}};
        Matrix2D m1=new Matrix2D();
        printMatrix(m1.mat);
//        m1.matrixMultiply(arr);
//        printArray(m1.matrix);
        Random rnd=new Random();
        double theta = rnd.nextFloat() * Math.PI/2;
        Vector2D v1 = new Vector2D(Math.cos(theta), Math.sin(theta));
        Vector2D v2 = v1.perp();
        System.out.println(v1.x + " " + v1.y);
        System.out.println(v2.x + " " + v2.y);
        double angle=180/Math.PI;
        System.out.println("angle:"+theta*angle);
        System.out.println("atan "+Math.atan2(v1.y, v1.x)*angle);
        m1.rotate(v1, v2);
        printMatrix(m1.mat);
        
        new Matrix2D();

    }
}
